package com.starblink.android.basic.base.fragment

import android.content.Context
import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.starblink.android.basic.R
import com.starblink.android.basic.base.IBaseView
import com.starblink.android.basic.base.activity.AbsActivity
import com.starblink.android.basic.receiver.ConnectivityReceiver
import com.starblink.android.basic.sensorsdata.room.entity.SkAntEntity
import com.starblink.android.basic.sensorsdata.spm.GTrackerAssistUtils
import com.starblink.android.basic.sensorsdata.spm.event.TrackEvent
import com.starblink.android.basic.sensorsdata.spm.impl.SpmTrackHandler
import com.starblink.android.basic.util.bus.FlowBus
import com.starblink.android.basic.util.bus.FlowConst
import com.starblink.basic.ext.nowTime


/**
 * 普通的Fragment，基类Fragment
 */

abstract class AbsFragment : Fragment(), IBaseView,
    ConnectivityReceiver.ConnectivityReceiverListener {

    /**
     * 获取Context对象
     */
    protected lateinit var mActivity: FragmentActivity
    protected lateinit var mContext: Context
    protected var pageExposureValue: Int? = null

    abstract fun setContentView(inflater: LayoutInflater, container: ViewGroup?): View

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mActivity = requireActivity()
        mContext = requireActivity().applicationContext

        if (needRegisterNetworkChangeObserver()) {
            ConnectivityReceiver.registerObserver(this)
            ConnectivityReceiver.registerAnnotationObserver(this)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return transformRootView(setContentView(inflater, container))
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.setTag(R.id.fragment_root_tag, this@AbsFragment)
        //切换网络
        FlowBus.with<Boolean>(FlowConst.DEV_SWITCH).register(this) {
            if (it) {
                switchNetConfig()
            }
        }
    }

    override fun onDestroyView() {
        view?.setTag(R.id.fragment_root_tag, null)
        super.onDestroyView()
    }

    //用于转换根数图View(可以对其做一些别的操作,例如加入GLoading)
    protected open fun transformRootView(view: View): View {
        return view
    }

    /**
     * 只映射了onDestroy方法 取消任务
     */
    override fun onDestroy() {
        super.onDestroy()

        if (needRegisterNetworkChangeObserver()) {
            ConnectivityReceiver.unregisterObserver(this)
            ConnectivityReceiver.unregisterAnnotationObserver(this)
        }
    }

    /**
     * 是否需要注册监听网络变换
     */
    open protected fun needRegisterNetworkChangeObserver(): Boolean {
        return false
    }

    override fun popSelf() {
        parentFragmentManager.popBackStackImmediate()
    }

    override fun switchNetConfig() {}


    open fun spmPageId(): Int = 0

    open fun spmPageParams(): Map<String, String> = mapOf()

    open fun isSpmTrackWithLifecycle(): Boolean = false

    private var trackTimeTag = 0L

    protected open fun pageExposure(
        pageElementValue: Int = spmPageId(),
        params: Map<String, String> = spmPageParams()
    ) {
        this.pageExposureValue = pageElementValue
        SpmTrackHandler.addSingleTrackData(
            SkAntEntity(
                event = TrackEvent.pageExposure.value,
                spmCnt = GTrackerAssistUtils.fetchPageValue(pageElementValue),
                params = params
            )
        )
        trackTimeTag = nowTime()
    }

    protected open fun pageDisappear(
        pageElementValue: Int = spmPageId(),
        params: Map<String, String> = spmPageParams()
    ) {
        this.pageExposureValue = pageElementValue
        val delay = nowTime() - trackTimeTag
        SpmTrackHandler.addSingleTrackData(
            SkAntEntity(
                event = TrackEvent.pageStayTime.value,
                spmCnt = GTrackerAssistUtils.fetchPageValue(pageElementValue),
                params = mutableMapOf<String, String>().apply {
                    putAll(params)
                    put("duration", delay.toString())
                }
            )
        )
    }

    private var rect: Rect? =null

    override fun onResume() {
        super.onResume()
        if (isSpmTrackWithLifecycle() && (isVisible && userVisibleHint)) {
            pageExposure()
        }
    }

    override fun onPause() {
        super.onPause()
        if (isSpmTrackWithLifecycle() && (isVisible && userVisibleHint)) {
            if (rect == null) rect = Rect()
            if (view?.getLocalVisibleRect(rect) == true) {
                pageDisappear()
            }
        }
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (isSpmTrackWithLifecycle()) {
            if (isVisible) {
                pageExposure()
            } else {
                pageDisappear()
            }
        }
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isSpmTrackWithLifecycle() && isVisible) {
            if (isVisibleToUser) {
                pageExposure()
            } else {
                pageDisappear()
            }
        }
    }

}
